package com.megvii.corelib.data;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

public class BeanManager<T extends BaseBean>
{
    protected List<T> beanList = new ArrayList<>();

    protected HashMap<String, T> beanMap = new HashMap<>();

    protected HashMap<String, Integer> indexMap = new HashMap<>();

    protected Comparator<T> comparator;

    public BeanManager()
    {
        super();
        this.comparator = null;
    }

    public BeanManager(Comparator<T> comparator)
    {
        super();
        this.comparator = comparator;
    }

    public void setComparator(Comparator<T> comparator)
    {
        this.comparator = comparator;
    }

    public void update(T bean)
    {
        update(bean, true);
    }

    protected void update(T bean, boolean sortAndIndex)
    {
        if (bean == null)
        {
            return;
        }
        if (beanMap.containsKey(bean.id))
        {
            beanMap.put(bean.id, bean);
            int index = indexMap.get(bean.id);
            beanList.set(index, bean);
        }
        else
        {
            beanList.add(bean);
            beanMap.put(bean.id, bean);
            if (sortAndIndex)
            {
                sortAndIndex();
            }
        }
    }

    public void update(Collection<T> beans)
    {
        if (beans == null)
        {
            return;
        }
        for (T bean : beans)
        {
            update(bean, false);
        }
        sortAndIndex();
    }

    public T get(String id)
    {
        if (id != null)
        {
            return beanMap.get(id);
        }
        else
        {
            return null;
        }
    }

    public List<T> getAll()
    {
        ArrayList<T> list = new ArrayList<>();
        list.addAll(beanList);
        return list;
    }

    public void remove(String id)
    {
        if (id != null && beanMap.containsKey(id))
        {
            int index = indexMap.remove(id);
            beanList.remove(index);
            beanMap.remove(id);
            sortAndIndex();
        }
    }

    public void clear()
    {
        beanList.clear();
        beanMap.clear();
        indexMap.clear();
    }

    public int size()
    {
        return beanList.size();
    }

    public boolean isEmpty()
    {
        return beanList.isEmpty();
    }

    protected void sortAndIndex()
    {
        if (comparator != null)
        {
            Collections.sort(beanList, comparator);
        }
        int i = 0;
        for (T visitor : beanList)
        {
            indexMap.put(visitor.id, i);
            i++;
        }
    }
}
